
<h2>Explanation of Example</h2>

<p>
<span class="title">I. Action API</span>
<br>Package <b><tt>example.common.action</tt></b> contains Action API.
<br>Package <b><tt>example.app.handler</tt></b> contains handlers for this actions.

<p>Example of using this API from <tt>example.web.AppServlet</tt>:
<pre class="brush: java;">
public void doGet(HttpServletRequest req, HttpServletResponse resp) {

	int pageIndex = ...;
	int limit = ...;
	
	GetDocsPage action = new GetDocsPage(pageIndex, limit);
	Page&lt;Doc> page = app.invoke(action);
	
	req.setAttribute("page", page);
	
}

public void doPost(HttpServletRequest req, HttpServletResponse resp) {
	
	int id = ...;
	String newName = ...;
	
	RenameDoc action = new RenameDoc(id, newName);
	app.invoke(action);
	
}</pre>


<br>Example of app handler:
<pre class="brush: java;">
package example.app.handler;

@Mapping(GetDocsPage.class)
public class GetDocsPageHandler extends Handler&lt;GetDocsPage>{
	
	@Inject
	Storage storage;

	@Override
	public void invoke(GetDocsPage action) throws Exception {
		
		Input input = action.input();
		int updatedPageIndex = input.pageIndex;
		int updatedLimit = input.limit;
		
		if(updatedPageIndex < 0){
			updatedPageIndex = 0;
		}
		
		if(updatedLimit < 0){
			updatedLimit = 0;
		} else if(updatedLimit > 50){
			updatedLimit = 50;
		}
		
		input.limit = updatedLimit;
		input.pageIndex = updatedPageIndex;
		
		storage.invoke(action);
		
	}

}</pre>



<p class="more-top">
<span class="title">II. App Layer</span>
<br>
Class <tt>example.web.AbstractInitServlet</tt> contains setup of App's <a target="_blank" href="./single-page.html#engine">Engine</a>:
<pre class="brush: java;">
public abstract class AbstractInitServlet extends HttpServlet {



	private App createApp(ServletConfig config) {
		
		Storage storage = createStorage(config);
		
		//create app's engine
		Engine engine = new Engine("App Engine");
		
		//init
		engine.addToContext(storage);
		engine.scanAndPut(App.class);
		engine.setConfig(TraceHandlers.class, true);
		
		//invoke actions
		engine.invoke(new CreateDataBase());
		
		//return Application
		return new AppImpl(engine);
	}
	
}
</pre>



<p class="more-top">
<span class="title">III. Storage Layer</span>
<br>
Class <tt>jdbc.web.InitServlet</tt> contains setup of Storage's <a target="_blank" href="./single-page.html#engine">Engine</a>:
<pre class="brush: java;">
public class InitServlet extends AbstractInitServlet {



	protected Storage createStorage(ServletConfig config) {
		
		//create storage's engine
		Engine engine = new Engine("Storage Engine");
		
		//init
		engine.addToContext(createTxManager());
		engine.addToContext(createDataSourceManager(config));
		
		engine.putFilter(UserTransactionInInvoke.class);
		engine.putFilter(ConnectionInInvoke.class);
		
		engine.scanAndPut("jdbc.storage");
		
		//return Storage
		return new StorageImpl(engine);
	}
}
</pre>


<br>Example of storage handler:
<pre class="brush: java;">
package jdbc.storage.handler;

@Mapping(GetDocsPage.class)
public class GetDocsPageHandler extends Handler&lt;GetDocsPage>{

	@Inject
	Connection c;
	
	@Override
	public void invoke(GetDocsPage action) throws Exception {
		
		Input input = action.input();
		
		int limit = input.limit;
		int pageIndex = input.pageIndex;
		int offset = pageIndex*limit;
		
		Statement st = c.createStatement();
		ResultSet rs = st.executeQuery("SELECT * FROM doc LIMIT "
			+limit+" OFFSET "+offset);
		
		ArrayList&lt;Doc> list = new ArrayList&lt;Doc>();
		while(rs.next()){
			list.add(convert(rs));
		}
		st.close();
		
		Integer count = subInvoke(new GetDocsCount());

		action.setOutput(new Page&lt;Doc>(list, pageIndex, limit, count));
		
	}

	private Doc convert(ResultSet rs) throws Exception {
		Doc doc = new Doc();
		doc.id = rs.getInt(1);
		doc.name = rs.getString(2);
		return doc;
	}

}</pre>



